from flask import Flask, request, jsonify, send_file, render_template
from flask_cors import CORS
import os
import tempfile
import threading
import uuid
import glob
from pipeline import Pipeline

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})

# 配置 MinIO 和输出目录
MINIO_ENDPOINT = "192.168.200.23:16689"
MINIO_ACCESS_KEY = "PZKHAKYKLv8djoTE"
MINIO_SECRET_KEY = "eHCt6bsoBlXdMkgCjoA09ZBgFxEPjiJw"
BUCKET_NAME = "dify"
OUTPUT_DIR = "output"

# 创建 Pipeline 实例
pipeline = Pipeline(
    minio_endpoint=MINIO_ENDPOINT,
    minio_access_key=MINIO_ACCESS_KEY,
    minio_secret_key=MINIO_SECRET_KEY,
    bucket_name=BUCKET_NAME,
    output_dir=OUTPUT_DIR
)

# 存储任务结果和进度
task_results = {}


def process_pdf_in_background(task_id, temp_pdf_path, original_filename):
    try:
        task_results[task_id] = {"status": "processing", "progress": 0}

        # 1. 解析 PDF
        task_results[task_id]["progress"] = 20
        task_results[task_id]["message"] = "正在解析 PDF..."

        # 2. 处理文档内容，并传递原始文件名，生成Markdown文件
        md_file_path = pipeline.run(temp_pdf_path, original_filename)

        task_results[task_id]["progress"] = 60
        task_results[task_id]["message"] = "正在生成 Markdown..."

        # 3. 上传图像到 MinIO
        if md_file_path:
            task_results[task_id]["progress"] = 80
            task_results[task_id]["message"] = "正在上传图片..."

            task_results[task_id]["progress"] = 100
            task_results[task_id]["status"] = "complete"
            task_results[task_id]["md_file_path"] = md_file_path
            task_results[task_id]["message"] = "任务完成"
        else:
            task_results[task_id]["status"] = "failed"
            task_results[task_id]["message"] = "转换失败"
            task_results[task_id]["progress"] = 100
    except Exception as e:
        task_results[task_id] = {"status": "failed", "message": str(e), "progress": 100}

def process_word_in_background(task_id, temp_word_path, original_filename):
    try:
        task_results[task_id] = {"status": "processing", "progress": 0}

        # 1. 解析 Word
        task_results[task_id]["progress"] = 20
        task_results[task_id]["message"] = "正在解析 Word 文档..."

        # 2. 处理文档内容，并传递原始文件名，生成Markdown文件
        md_file_path = pipeline.process_word(temp_word_path, original_filename)

        task_results[task_id]["progress"] = 60
        task_results[task_id]["message"] = "正在生成 Markdown..."

        # 3. 上传图像到 MinIO
        if md_file_path:
            task_results[task_id]["progress"] = 80
            task_results[task_id]["message"] = "正在上传图片..."

            task_results[task_id]["progress"] = 100
            task_results[task_id]["status"] = "complete"
            task_results[task_id]["md_file_path"] = md_file_path
            task_results[task_id]["message"] = "任务完成"
        else:
            task_results[task_id]["status"] = "failed"
            task_results[task_id]["message"] = "转换失败"
            task_results[task_id]["progress"] = 100
    except Exception as e:
        task_results[task_id] = {"status": "failed", "message": str(e), "progress": 100}

@app.route('/convert', methods=['POST'])
def convert_pdf():
    if 'file' not in request.files:
        return jsonify({"error": "No file part"}), 400

    file = request.files['file']
    if file.filename == '':
        return jsonify({"error": "No selected file"}), 400

    if file and file.filename.endswith('.pdf'):
        # 使用UUID生成唯一任务ID
        task_id = str(uuid.uuid4())

        original_filename = os.path.splitext(file.filename)[0]  # 获取不带扩展名的文件名

        with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as temp_pdf:
            file.save(temp_pdf.name)
            temp_pdf_path = temp_pdf.name

        task_results[task_id] = {"status": "processing", "progress": 0}

        thread = threading.Thread(target=process_pdf_in_background, args=(task_id, temp_pdf_path, original_filename))
        thread.start()

        return jsonify({"status": "processing", "task_id": task_id}), 202
    else:
        return jsonify({"error": "Invalid file type. Only PDF files are allowed."}), 400


@app.route('/convert_word', methods=['POST'])
def convert_word():
    if 'file' not in request.files:
        return jsonify({"error": "No file part"}), 400

    file = request.files['file']
    if file.filename == '':
        return jsonify({"error": "No selected file"}), 400

    if file and file.filename.endswith('.docx'):
        # 使用UUID生成唯一任务ID
        task_id = str(uuid.uuid4())

        original_filename = os.path.splitext(file.filename)[0]  # 获取不带扩展名的文件名

        with tempfile.NamedTemporaryFile(delete=False, suffix='.docx') as temp_word:
            file.save(temp_word.name)
            temp_word_path = temp_word.name

        task_results[task_id] = {"status": "processing", "progress": 0}

        thread = threading.Thread(target=process_word_in_background, args=(task_id, temp_word_path, original_filename))
        thread.start()

        return jsonify({"status": "processing", "task_id": task_id}), 202
    else:
        return jsonify({"error": "Invalid file type. Only Word (.docx) files are allowed."}), 400


@app.route('/')
def index():
    return render_template('index.html')

@app.route('/files', methods=['GET'])
def get_files():
    """获取已转换的文件列表"""
    files = []
    # 获取output目录下的所有md文件
    md_files = glob.glob(os.path.join(OUTPUT_DIR, "*.md"))
    
    for file_path in md_files:
        filename = os.path.basename(file_path)
        # 获取文件的修改时间
        mod_time = os.path.getmtime(file_path)
        # 获取文件大小
        size = os.path.getsize(file_path)
        
        files.append({
            "filename": filename,
            "path": file_path,
            "modified_time": mod_time,
            "size": size
        })
    
    # 按修改时间降序排序，最新的文件排在前面
    files.sort(key=lambda x: x["modified_time"], reverse=True)
    
    return jsonify({"files": files})

@app.route('/download_file/<path:filename>', methods=['GET'])
def download_file(filename):
    """下载指定的文件"""
    file_path = os.path.join(OUTPUT_DIR, filename)
    if os.path.exists(file_path):
        quoted_filename = quote(filename)  # 对文件名进行 URL 编码
        
        # 生成响应并设置 Content-Disposition
        response = make_response(send_file(file_path))
        response.headers["Content-Disposition"] = f"attachment; filename*=UTF-8''{quoted_filename}"
        
        # 允许前端访问 Content-Disposition 头
        response.headers["Access-Control-Expose-Headers"] = "Content-Disposition"
        return response
    else:
        return jsonify({"error": "文件未找到"}), 404

from urllib.parse import quote
from flask import send_file, make_response


@app.route('/download/<task_id>', methods=['GET'])
def download_md(task_id):
    if task_id in task_results and task_results[task_id]["status"] == "complete":
        md_file_path = task_results[task_id]["md_file_path"]
        if os.path.exists(md_file_path):
            filename = os.path.basename(md_file_path)
            quoted_filename = quote(filename)  # 对文件名进行 URL 编码

            # 生成响应并设置 Content-Disposition
            response = make_response(send_file(md_file_path))
            response.headers["Content-Disposition"] = f"attachment; filename*=UTF-8''{quoted_filename}"

            # 允许前端访问 Content-Disposition 头
            response.headers["Access-Control-Expose-Headers"] = "Content-Disposition"
            return response
        else:
            return jsonify({"error": "文件未找到"}), 404
    else:
        return jsonify({"error": "任务未完成或任务 ID 无效"}), 404


@app.route('/progress/<task_id>', methods=['GET'])
def check_progress(task_id):
    if task_id in task_results:
        return jsonify(task_results[task_id])
    else:
        return jsonify({"error": "Invalid task ID"}), 404


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=1060)
